<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        event = 'click'
        callback = function () {
            console.log('click')
        }
        //发布订阅模式  发布者，事件总线， 订阅者

        class HMEmitter {
            #handlers = {
                //事件名字： 对应的回调数组
            }
            //注册事件 1.私有属性 2.保存事件
            $on(event, callback) {
                if (!this.#handlers[event]) {
                    this.#handlers[event] = []
                }
                this.#handlers[event].push(callback)
            }
            //触发事件 1.不定长参数 2.遍历数组 3.执行数组中的函数
            $emit(event, ...args) {
                const funcs = this.#handlers[event] || []
                //空数组forEach没意义，但是没有空数组，可能会抛出错误
                if (funcs) {
                    funcs.forEach(callback => callback(...args))
                }

            }
            //移除事件
            $off(event) {
                delete this.#handlers[event]
            }
            //只执行一次
            $once(event, callback) {
                const onceCallback = (...args) => {
                    callback(...args)
                    this.$off(event)
                }
                this.$on(event, onceCallback)
            }
        }
        const bus = new HMEmitter()
        // // 第一次注册 click 事件
        // this.#handlers = {}  // 初始状态
        // // 经过 if 判断后创建了数组
        // this.#handlers = { click: [] }
        // // 执行 push
        // this.#handlers['click'].push(function () { console.log('clicked') })
        // // 结果: this.#handlers = { click: [function() { console.log('clicked') }] }

        // // 第二次注册 click 事件
        // this.#handlers = { click: [firstCallback] }
        // // 跳过 if 判断，直接执行 push
        // this.#handlers['click'].push(function () { console.log('clicked again') })
        // // 结果: this.#handlers = { click: [firstCallback, secondCallback] }


    </script>
</body>

</html>